#pragma once
#include <string>
#include <cstddef> // std::size_t

/*
 在 C++ 中，要使用 ODB 将类声明为持久化类，需要包含 ODB 的核心头文
件，并使用 #pragma db object 指令
 #pragma db object 指示 ODB 编译器将 person 类视为一个持久化类。
*/
#include <odb/core.hxx>
#include <odb/nullable.hxx>

#include"chat_session_member.hxx"

namespace bite_im
{
    enum class ChatSessionType
    {
        SINGLE = 1,
        GROUP = 2
    };
#pragma db object table("chat_session") // 用户关系表映射结构
    class ChatSession
    {
    public:
        ChatSession() {}

        ChatSession(const std::string &chat_session_id,
                    const std::string &chat_session_name,
                    const ChatSessionType chat_session_type)
            : _chat_session_id(chat_session_id),
              _chat_session_name(chat_session_name),
              _chat_session_type(chat_session_type) {}

        void chat_session_id(const std::string &val) { _chat_session_id = val; }
        std::string chat_session_id() const { return _chat_session_id; }

        void chat_session_name(const std::string &val) { _chat_session_name = val; }
        std::string chat_session_name() const { return _chat_session_name; }

        ChatSessionType chat_session_type() const { return _chat_session_type; }
        void chat_session_type(const ChatSessionType val) { _chat_session_type = val; }
    private:
        friend class odb::access;
        //_id 成员前面的 pragma 告诉 ODB 编译器，以下成员是对象的标识符。auto 说明符指示它是数据库分配的 ID。
#pragma db id auto // 表示 ID 字段将自动生成（通常是数据库中的主键），在哪个上面就是主键
        unsigned long _id;

#pragma db type("varchar(64)") index unique
        std::string _chat_session_id;
#pragma db type("varchar(64)")
        std::string _chat_session_name;
#pragma db type("tinyint")
        ChatSessionType _chat_session_type; // 1-两人聊天 2-群聊

    };


        //  view构建联合查询表ChatSession和ChatSessionMember
        /*
        原理:   首先我们有一个ChatSession表，里面有_chat_session_id字段，我们可以通过这个字段在ChatSessionMember里进行查询，
                我们知道单聊会在ChatSessionMember中拥有两条数据，并且这两条数据都是对应_chat_session_id == _session_id
                但是这时我们需要的是当前的user_id所对应的对面的对象的这条数据所以我们最后需要指定条件来进行过滤
        */
        // 过滤条件: css::_chat_session_type == 1 && csm1._user_id == user_id（外部传入） &&  csm2._user_id != csm1._user_id
        // ChatSession = css，ChatSessionMember = csm2表示分别取别名为css csm2
        #pragma db view object(ChatSession = css) \
        object(ChatSessionMember = csm1 : css::_chat_session_id == csm1::_session_id) \
        object(ChatSessionMember = csm2 : css::_chat_session_id == csm2::_session_id) \
        query((?))
        struct SingleChatSession        // 获取某个用户的所有单聊对应的friend_id和session_id
        {
        #pragma db column(css::_chat_session_id)
        std::string chat_session_id;
        #pragma db column(csm2::_user_id)
        std::string friend_id;
        };
        
        // 过滤条件: css::_chat_session_type == 2 && csm1._user_id == user_id（外部传入）
        #pragma db view object(ChatSession = css) \
        object(ChatSessionMember = csm1 : css::_chat_session_id == csm1::_session_id) \
        query((?))
        struct GroupChatSession
        {
        #pragma db column(css::_chat_session_id)
        std::string chat_session_id;
        #pragma db column(css::_chat_session_name)
        std::string chat_session_name;
        };

}


// odb -d mysql --std c++11 --generate-query --generate-schema  message.hxx
//  生成数据库后记得进入message_sql来给ChatRoom生成表